<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Reflect对象提供的方法</title>
    <script src="js/traceur.js"></script>
    <script src="js/bootstrap.js"></script>
    <script type="module">

        //apply方法：用于调用具有给定此值的函数
        function function_name(a, b, c) {
            return this.value + a + b + c;
        }
        var returned_value = Reflect.apply(function_name, {value: 100}, [10, 20, 30]);
        console.log(returned_value); // 160

        //construct():返回由目标构造函数创建的新实例
        function constructor1(a, b) {
            this.a = a;
            this.b = b;
            this.f = function () {
                return this.a + this.b + this.c;
            }
        }
        function constructor2() {
        }
        constructor2.prototype.c = 100;
        var myObject = Reflect.construct(constructor1, [1, 2], constructor2);
        console.log(myObject.f()); //"103"

        //defineProperty():直接在对象上定义一个新属性并赋值
        //创建data属性
        var obj = {}
        Reflect.defineProperty(obj, "name", {
            value: "Eden",
            writable: true,
            configurable: true,
            enumerable: true
        });
        console.log(obj.name); // "Eden"

        var obj = {
            __name__: "Eden"
        }
        //accessor属性
        Reflect.defineProperty(obj, "name", {
            get: function () {
                return this.__name__;
            },
            set: function (newName) {
                this.__name__ = newName;
            },
            configurable: true,
            enumerable: true
        });
        obj.name = "John";
        console.log(obj.name); // "John"

        //deleteProperty()方法用于删除对象的属性
        var obj = {
            name: "Eden"
        }
        console.log(obj.name); // "Eden"
        Reflect.deleteProperty(obj, "name");
        console.log(obj.name); // "undefined"

        //enumerate()方法将一个对象作为参数，并返回一个表示对象的可枚举属性的迭代器对象
        //好像无法使用了，无语
        var obj = {
            a: 1,
            b: 2,
            c: 3
        };
        //        var iterator = Reflect.enumerate(obj);
        //        console.log(iterator.next().value);  //a
        //        console.log(iterator.next().value);  // b
        //        console.log(iterator.next().value);  //c
        //        console.log(iterator.next().done); //true

        //get()方法：用于检索对象属性的值
        var obj = {
            __name__: "Eden"
        };
        Reflect.defineProperty(obj, "name", {
            get: function () {
                return this.__name__;
            }
        });
        console.log(obj.name); //"Eden"
        var name = Reflect.get(obj, "name", {__name__: "John"});
        console.log(name); //"John"

        //set()方法用于设置对象属性的值
        var obj1 = {
            __name__: "Eden"
        };
        Reflect.defineProperty(obj1, "name", {
            set: function (newName) {
                this.__name__ = newName;
            },
            get: function () {
                return this.__name__;
            }
        });
        var obj2 = {
            __name__: "John"
        };
        Reflect.set(obj1, "name", "Eden", obj2);
        console.log(obj1.name); // "Eden"
        console.log(obj2.__name__); // "Eden"

        //getOwnPropertyDescriptor()方法用于检索对象属性的描述符
        var obj = {
            name: "Eden"
        };
        var descriptor = Reflect.getOwnPropertyDescriptor(obj, "name");
        console.log(descriptor.value); //Eden
        console.log(descriptor.writable); // true
        console.log(descriptor.enumerable); //true
        console.log(descriptor.configurable); //true

        //Reflect.getPrototypeOf()方法用于检索对象的原型
        var obj1 = {
            __proto__: {
                name: "Eden"
            }
        };
        var obj2 = Reflect.getPrototypeOf(obj1);
        console.log(obj2.name); // "Eden"

        //setPrototypeOf()用于设置对象的内部[[prototype]]属性的值
        var obj = {};
        Reflect.setPrototypeOf(obj, {
            name: "Eden"
        });
        console.log(obj.name); //"Eden"

        //isExtensible()方法用于检查对象是否可扩展
        var obj = {
            name: "Eden"
        };
        console.log(Reflect.isExtensible(obj)); // "true"
        Object.preventExtensions(obj);
        console.log(Reflect.isExtensible(obj)); // "false"

        //preventExtensions()用于将对象标记为不可扩展
        var obj = {
            name: "Eden"
        };
        console.log(Reflect.isExtensible(obj)); // "true"
        console.log(Reflect.preventExtensions(obj)); // "true"
        console.log(Reflect.isExtensible(obj)); //"false"

        //ownKeys()方法返回一个数组，其值表示提供的对象的属性的键。
        var obj = {
            a: 1,
            b: 2,
            __proto__: {
                c: 3
            }
        };
        var keys = Reflect.ownKeys(obj);
        console.log(keys.length); // "2"
        console.log(keys[0]); // "a"
        console.log(keys[1]); // "b"
    </script>
</head>
<body>

</body>
</html>